#include<stdlib.h>
#include"./HostMemPool.hpp"


namespace MMF
{

    namespace Details
    {
        void* aligned_alloc(uint32_t alignment, uint64_t size)
        {
        #ifdef WIN32
            return _aligned_malloc(size, alignment);
        #else 
            return ::aligned_alloc(size, alignment);
        #endif
        }
    }

    MMFHostMemPool::MMFHostMemPool(uint64_t blockSize, uint64_t blockNum)
        : mSize(blockSize * blockNum)
    {}


    MMFHostMemPool::MMFHostMemPool(MMFHostMemPool&& that)
        : mSize(that.mSize)
        , mBuffer(that.mBuffer)
    {
        that.mBuffer = nullptr;
    }


    MMFHostMemPool& MMFHostMemPool::operator=(MMFHostMemPool&& that)
    {
        mSize = that.mSize;
        mBuffer = that.mBuffer;
        that.mBuffer = nullptr;
        return *this;
    }

    
    MMFHostMemPool::~MMFHostMemPool()
    {
        if (mBuffer != nullptr)
            Deallocate();
    }


    void* MMFHostMemPool::Allocate()
    {
        void* buff = nullptr;
        if (mSize > 4096)
            Details::aligned_alloc(MMF_PAGE_SIZE, mSize);
        else 
            buff = malloc(mSize);

        mBuffer = buff;
        return buff;
    }


    void MMFHostMemPool::Deallocate()
    {
        ::free(mBuffer);
        mBuffer = nullptr;
    }


    uint64_t MMFHostMemPool::Bytes()
    {
        return mSize;
    }


    MMFBufferPoolType MMFHostMemPool::Type()
    {
        return MMFBufferPoolType::HOST;
    }
}